home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / asm3.zip / PR.ASM < prev    next >
Assembly Source File  |  1986-02-05  |  20KB  |  324 lines

  1. ;
  2. ;
  3. CSEG     segment para public 'CODE'
  4.         assume cs:cseg,ds:cseg,ss:cseg,es:cseg
  5.     org     100h                 ; .COM file format
  6. BEGIN:    jmp     PR_MAIN                 ; Skip around data declarations
  7.     COPYRIGHT     db      'PRint (C) 1985, Dickinson Associates Inc.'
  8.                         db     13,10,'$'
  9.         VALID_IN        db      '/abcdefghijklmnopqrstuvwxyz,;=',9
  10.         VALID_OUT       db      '\ABCDEFGHIJKLMNOPQRSTUVWXYZ',4 dup(32)
  11.         VALID_NUM       equ     $ - VALID_OUT + 1
  12.         FN_AREA         db      77 dup (0)
  13.         FN_LOC          dw      offset FN_AREA  ; Initialize at FN_AREA
  14.         PRN             equ     4               ; PC-DOS printer device handle
  15.         MAX_LINES       equ    55
  16.         MAX_CHARS       equ    80
  17.         FILE_HANDLE     dw      0
  18.         READ_LENGTH     equ     256
  19.         READ_BUFFER     db     READ_LENGTH dup (0),0
  20.         READ_PTR        dw    offset READ_BUFFER
  21.         PRINT_LENGTH    equ     256
  22.         PRINT_BUFFER    db      PRINT_LENGTH dup (0)
  23.         PRINT_PTR       dw      offset PRINT_BUFFER
  24.         EOF_FOUND       db      0
  25.         CHAR_COUNT      dw      0
  26.         LINE_COUNT      db      0
  27.         PAGE_COUNT      db      0
  28.         BIN_ASC         db     10
  29.         HEAD_1          db      13,10,13,10,'*',78 dup ('-'),'*',13,10
  30.         HEAD_2A         db      '|  File: '
  31.         HEAD_2B         db      70 dup (' '),'|',13,10
  32.         HEAD_3A         db      '| Saved: '
  33.         HEAD_3B         db      '00-00-00 at '
  34.         HEAD_3C         db      '00:00:00 '
  35.         HEAD_3D         db      '0m',39 dup (' '),'Page '
  36.         HEAD_3E         db     '00 |',13,10
  37.         HEAD_4          db      '*',78 dup ('-'),'*',13,10,13,10
  38.         HEAD_LGTH       dw      $ - HEAD_1
  39.         ERR_HEAD        db      10,13,'PRint Error - $'
  40.         NO_FILE         db      'Correct Syntax is:',13,10,10
  41.                         db      'PR [d:][path]filename[.ext]$'
  42.         FILE_NOT_FOUND  db      'File Not Found$'
  43.         OPEN_FAILURE    db      'File Open Failure$'
  44.         READ_FAILURE    db      'File Read Failure$'
  45.         ERR_TAIL        db      10,10,13,' . . . Aborting',10,13,13,'$'
  46. ;
  47. PR_MAIN            proc    near            ; PR's main program
  48.         lea    dx,COPYRIGHT                         ; Display copyright notice
  49.         mov     ah,9h                   ; Request display string
  50.         int     21h                ; Call PC-DOS
  51.         mov     si,80h                  ; Point SI to beginning of PSP parm area
  52.         lea     di,FN_AREA              ; Point SI to internal file name area
  53.         mov     cl,byte ptr [si]        ; Get byte count to AL
  54.         xor     ch,ch                   ; Zero CH
  55.         jcxz    NONE                    ; If CX is zero, no parameters passed
  56.         cld                             ; Set direction flag to forward
  57.         inc     si                      ; Adjust SI to beginning of parms
  58.         mov     dx,0                    ; Use DX for leading blanks flag
  59. CLEAN:  lodsb                           ; Load each character to AL
  60.         push    di                      ; Save DI on stack
  61.         mov     di,offset VALID_IN      ; Point to table of valid inputs
  62.         push    cx                      ; Save CX on stack
  63.         mov     cx,VALID_NUM            ; Set CX to number of inputs to look for
  64. repne   scasb                           ; See if any are in AL
  65.         jcxz    CLEAND                  ; If not, change nothing
  66.         mov     bx,VALID_NUM            ; Set up BX to point to valid output
  67.         sub     bx,cx                   ; This will leave BX one off
  68.         mov     al,VALID_OUT [bx - 1]   ; Load the valid output (adj BX) to AL
  69. CLEAND: pop     cx                      ; Restore CX
  70.         pop     di                      ; Restore DI
  71.         cmp     dx,1                    ; If leading blanks have been stripped,
  72.         je      CLEANC                  ; go check for colons & other things
  73.         cmp     al,' '                  ; Is AL a leading blank?
  74.         je      CLEANX                  ; Yes, ignore it & don't store it
  75. CLEANC: mov     dx,1                    ; If here, leading blanks are stripped
  76.         cmp     al,':'                  ; Is AL a colon?
  77.         je      DELIM                   ; Yes, it's a potential FN delimiter
  78.         cmp     al,'\'                  ; Is AL a backslash?
  79.         jne     DELIMX                  ; Yes, it's a potential FN delimiter
  80. DELIM:  mov     FN_LOC,di               ; Set FN_LOC at current DI + 1
  81.         inc     FN_LOC                  ; -- last one set will be correct
  82. DELIMX: stosb                           ; Store modified AL back to PSP
  83. CLEANX: loop    CLEAN                   ; Loop until CX is zero
  84.         jmp     FINDF                   ; Go see if file exists
  85. NONE:   lea     dx,NO_FILE              ; Exit with error if no parameter
  86.         jmp     EREXIT                  ; passed
  87. FINDF:  mov     ah,4eh                  ; Request find 1st file
  88.         mov     cx,0                    ; Set CX for normal files
  89.         lea     dx,FN_AREA              ; Point DX to internal file name area
  90.         int     21h                     ; Call PC-DOS
  91.         jnc     FOUNDF                  ; Ok, found the 1st file
  92.         lea     dx,FILE_NOT_FOUND       ; If 1st file not found, exit
  93.         jmp     EREXIT                  ; with error
  94. FOUNDF: mov     EOF_FOUND,0             ; Initialize end of file flag
  95.         mov     PAGE_COUNT,0            ; Initialize page counter
  96.         mov     FILE_HANDLE,0           ; Initialize file handle
  97.         mov     di,FN_LOC               ; DI points to end of path
  98.         mov     si,9eh                  ; SI points to file name in default DTA
  99.         mov     cx,13                   ; DTA file name has 13 bytes
  100. rep     movsb                           ; Move bytes to FN_LOC (in FN_AREA)
  101.         mov     ah,3dh                  ; Request open file pointed to by DX
  102.         mov     al,0                    ; Read permission requested
  103.         lea     dx,FN_AREA              ; Internal File Name Area
  104.         int     21h                     ; Call PC-DOS
  105.         mov     FILE_HANDLE,ax          ; Save File Handle contained in AX
  106.         jnc     DO_PR                   ; No carry means successfully opened
  107.         lea     dx,OPEN_FAILURE         ; Open file failed, exit
  108.         jmp     EREXIT                  ; with error message
  109. DO_PR:  call    STAMP                   ; Set file name, date & time stamps
  110.         call    PAGE_HEAD               ; Print page header
  111.         mov     di,PRINT_PTR            ; Initialize DI to PRINT_BUFFER
  112. PRLOOP: call    READ_FILE               ; Read data to buffer
  113.         jc      EREXIT                  ; Exit if error
  114.         jcxz    FINISH                  ; If CX is zero, end of file was reached
  115.         call    PRINT                   ; Format and print buffered data
  116.         cmp     EOF_FOUND,0             ; Was end of file flag set?
  117.         je      PRLOOP                  ; No, keep going
  118. FINISH: call    NEW_PAGE                ; Yes, print page feed
  119.         call    CLOSE_FILE              ; Close file
  120.         mov     ah,4fh                  ; Request find next file
  121.         mov     cx,0                    ; Set CX for normal files
  122.         int     21h                     ; Call PC-DOS
  123.         jnc     FOUNDF                  ; If no carry then found the next file
  124. EXIT:   ret                             ; If carry, exit to  PC-DOS
  125. EREXIT: push    dx                      ; Save error message pointer on stack
  126.         mov     dx,offset ERR_HEAD      ; Display error header
  127.         mov     ah,9                    ; Request display string
  128.         int     21h                     ; Call PC-DOS
  129.         pop     dx                      ; Restore error message pointer
  130.         mov     ah,9                    ; Request display string
  131.         int     21h                     ; Call PC-DOS
  132.         mov     dx,offset ERR_TAIL      ; Display error tail
  133.         mov     ah,9                    ; Request display string
  134.         int     21h                     ; Call PC-DOS
  135.         call    CLOSE_FILE              ; Close any open file
  136.         jmp     EXIT                    ; Go exit to PC-DOS (all errors fatal)
  137. PR_MAIN         endp
  138. ;
  139. READ_FILE       proc     near           ; Load CX bytes to read buffer
  140.     mov     bx,FILE_HANDLE          ; Set BX to current File Handle
  141.         mov     dx,READ_PTR             ; Point DX to read buffer
  142.         mov     cx,READ_LENGTH          ; Set CX to read buffer length
  143.         mov     ah,3fh                  ; Request read file
  144.         int     21h                     ; Call PC-DOS
  145.         jnc     RD_OK                   ; No carry, then read was Ok
  146.         lea     DX,READ_FAILURE         ; Can't imagine what error occurred
  147.         jmp     EX_RD                   ; unless coding error in file handle
  148. RD_OK:  cmp     cx,ax                   ; If CX chars were read (noted in AX)
  149.         je      NO_EOF                  ; then not at end of file (CF clears)
  150.         mov     EOF_FOUND,1             ; Otherwise, end of file reached
  151. NO_EOF: mov     cx,ax                   ; Refresh CX in case end of file reached
  152. EX_RD:  ret                             ; Return to caller
  153. READ_FILE        endp
  154. ;
  155. PRINT   proc     near                   ; Format and print output buffer
  156.         mov      si,READ_PTR            ; Set SI to read buffer
  157. FORMAT: cmp      LINE_COUNT,MAX_LINES   ; Is page full?
  158.         jb       LOAD                   ; No, go get next character
  159.         call     NEW_PAGE               ; Yes, print end of page / new page
  160.         call     PAGE_HEAD              ; Print page header
  161. LOAD:   lodsb                           ; Get character to AL
  162.         cmp      al,26                  ; Check for EOF character
  163.         je       AGAIN                  ; Ignore it
  164.         cmp      al,9                   ; Is AL a Tab?
  165.         jne      PUT_IT                 ; No, put char in print buffer
  166.         mov      al,32                  ; Load AL with blank to expand Tab
  167. TAB_X:  stosb                           ; Move AL to print buffer
  168.         inc      CHAR_COUNT             ; Increment line character counter
  169.         test     CHAR_COUNT,7           ; Is Tab expanded? (this does mod 8)
  170.         jnz      TAB_X                  ; No, keep loading blanks
  171.         jmp      WDTH                   ; Go check current line width
  172. PUT_IT: stosb                           ; Move AL to print buffer
  173.         inc      CHAR_COUNT             ; Increment line character counter
  174.         cmp      al,13                  ; Is AL a CR?
  175.         je       AGAIN                  ; Yes, go force next character
  176.         cmp      al,10                  ; Is AL a LF?
  177.         jne      FF                     ; No, check for Form Feed
  178.         call     PRINT_LINE             ; Yes, print current output buffer
  179.         jmp      AGAIN                  ; Go get next character
  180. FF:     cmp      al,12                  ; Is AL a Form Feed?
  181.         jne      WDTH                   ; No, check current width
  182.         call     NEW_PAGE               ; Yes, print end of page / new page
  183.         call     PAGE_HEAD              ; Print page header
  184.         jmp      AGAIN                  ; Re-start loop
  185. WDTH:   cmp      CHAR_COUNT,MAX_CHARS   ; Is buffer full?
  186.         jb       AGAIN                  ; No, go get next character
  187.         cmp      byte ptr [si],13       ; Yes, see if CR is next character
  188.         je       AGAIN                  ; Yes, then go get it and continue
  189.         mov      ah,10                  ; No, force CR,LF sequence
  190.         mov      al,13                  ; into print buffer
  191.         stosw                           ; Move AX to print buffer
  192.         add      CHAR_COUNT,2           ; Add two bytes to character counter
  193.         call     PRINT_LINE             ; Print the line
  194. AGAIN:  loop     FORMAT                 ; Loop bottom
  195.         ret                             ; Return to caller
  196. PRINT   endp
  197. ;
  198. PRINT_LINE       proc    near           ; Print a full or complete line
  199.         push     ax                     ; Save affected registers
  200.         push     cx                     ; currently in use
  201.         mov      dx,PRINT_PTR           ; Set DX to point to buffer
  202.         mov      cx,CHAR_COUNT          ; Print CHAR_COUNT characters
  203.         mov      bx,PRN                 ; PC-DOS printer device
  204.         mov      ah,40h                 ; Request write to device
  205.         int      21h                    ; Call PC-DOS - error unlikely here
  206.         mov      di,PRINT_PTR           ; Refresh DI
  207.         mov      CHAR_COUNT,0           ; Refresh CHAR_COUNT
  208.         inc      LINE_COUNT             ; Increment line counter
  209.         pop      cx                     ; Restore registers
  210.         pop      ax
  211.         ret                             ; Return to caller
  212. PRINT_LINE       endp
  213. ;
  214. NEW_PAGE         proc     near          ; Print end of page / new page
  215.         cmp      al,12                  ; Does AL have a form feed?
  216.         je       FF_OK                  ; Yes, so it's in the buffer
  217.         mov      al,12                  ; No, put one in the buffer
  218.         stosb                           ; Store AL in the buffer
  219.         inc      CHAR_COUNT             ; Increment character counter
  220. FF_OK:  call     PRINT_LINE             ; Print current buffer
  221.         mov      LINE_COUNT,0           ; Refresh line counter
  222.         ret                             ; Return to caller
  223. NEW_PAGE         endp
  224. ;
  225. PAGE_HEAD        proc     near          ; Format and print page header
  226.         push     di                     ; Save DI on stack
  227.         inc      PAGE_COUNT             ; Increase page counter
  228.         mov      al,PAGE_COUNT          ; Set up to convert page
  229.         lea      di,HEAD_3E             ; counter to ASCII
  230.         call     BIN_2_ASC              ; Convert to ASCII
  231.         pop      di                     ; Restore DI
  232.         cmp      HEAD_3E[0],'0'         ; Does page counter have leading 0?
  233.         jne      NOT_0                  ; No, don't do anything to it
  234.         mov      HEAD_3E[0],' '         ; Yes, make it a blank
  235. NOT_0:  push     cx                     ; Save CX on stack
  236.         mov      ah,40h                 ; Request write to device
  237.         mov      bx,PRN                 ; Request PC-DOS printer device
  238.         lea      dx,HEAD_1              ; Point to page header
  239.         mov      cx,HEAD_LGTH           ; Write all bytes in page header
  240.         int      21h                    ; Call PC-DOS
  241.         pop      cx                     ; Restore CX
  242.         ret                             ; Return to caller
  243. PAGE_HEAD        endp
  244. ;
  245. STAMP   proc     near       ; Move file name, date & time stamps to page header
  246.         lea      si,FN_AREA             ; Internal file name
  247.         lea      di,HEAD_2B             ; Location of file name in page header
  248.         mov      cx,70                  ; Load up to 70 chars in file name field
  249. LD_FN1: lodsb                           ; Get character to AL
  250.         cmp      al,0                   ; Is it the terminating zero?
  251.         je       LD_FN2                 ; Yes, go fill remainder with blanks
  252.         stosb                           ; No, store to page header field
  253.         loop     LD_FN1                 ; Loop until 0 found or CX zero
  254.         jcxz     DATE                   ; If out of room in page header, quit
  255. LD_FN2: mov      al,32                  ; Load rest of field with blanks
  256. rep     stosb
  257. DATE:   mov      si,98h                 ; Date position in default DTA
  258.         lea      di,HEAD_3B             ; Month position in page header
  259.         lodsw                           ; Packed word field
  260.         mov      bx,ax                  ; Make a copy in BX
  261.         and      ax,01e0h               ; Isolate month field
  262.         mov      cl,5                   ; Align to AL register
  263.         shr      ax,cl                  ; by shifting right 5 bits
  264.         call     BIN_2_ASC              ; Convert binary month to ASCII
  265.         mov      ax,bx                  ; Restore AX from BX
  266.         and      ax,1fh                 ; Isolate day field
  267.         inc      di                     ; Day position in page header
  268.         call     BIN_2_ASC              ; Convert binary day to ASCII
  269.         mov      ax,bx                  ; Restore AX from BX
  270.         and      ax,0fe00h              ; Isolate year field
  271.         shr      ah,1                   ; Shift right to align
  272.         add      ah,80                  ; AH is years since 1980
  273.         mov      al,ah                  ; Move to AL for division
  274.         inc      di                     ; Year position in page header
  275.         call     BIN_2_ASC              ; Convert binary year to ASCII
  276. TIME:   mov      si,96h                 ; Time position in default DTA
  277.         lea      di,HEAD_3C             ; Hours position in page header
  278.         lodsw                           ; Packed word field
  279.         mov      bx,ax                  ; Make a copy in BX
  280.         and      ax,0f800h              ; Isolate hours field
  281.         mov      cl,11                  ; Align to AL register
  282.         shr      ax,cl                  ; by shifting right 11 bits
  283.         mov      HEAD_3D[0],'a'         ; Assume it's an 'am' time
  284.         cmp      al,12                  ; Check for noon
  285.         jb       AM_OK                  ; If less, it's AM
  286.         je       PM_OK                  ; If equal, it's 12 PM
  287.         sub      al,12                  ; If more, it's after 12 PM
  288. PM_OK:  mov      HEAD_3D[0],'p'         ; Change 'am' to 'pm'
  289. AM_OK:  call     BIN_2_ASC              ; Convert binary hours to ASCII
  290.         mov      ax,bx                  ; Restore AX from BX
  291.         and      ax,7e0h                ; Isolate minutes field
  292.         mov      cl,5                   ; Align to AL register
  293.         shr      ax,cl                  ; by shifting right 5 bits
  294.         inc      di                     ; Minutes position in page header
  295.         call     BIN_2_ASC              ; Convert binary minutes to ASCII
  296.         mov      ax,bx                  ; Restore AX from BX
  297.         and      ax,1fh                 ; Isolate seconds field
  298.         inc      di                     ; Seconds position in page header
  299.         call     BIN_2_ASC              ; Convert binary seconds to ASCII
  300.         ret                             ; Return to caller
  301. STAMP   endp
  302. ;
  303. BIN_2_ASC        proc    near           ; Convert binary number to 2-digit ASCII
  304.         cbw                             ; Convert AL to word for division
  305.         div      BIN_ASC                ; Divide AL by BIN_ASC (contains a 10)
  306.         add      al,48                  ; Convert quotient (in AL) to ASCII
  307.         stosb                           ; Store to location pointed to by DI
  308.         add      ah,48                  ; Convert remainder (in AH) to ASCII
  309.         mov      al,ah                  ; Move to AL for store
  310.         stosb                           ; Store to location pointed to by DI
  311.         ret                             ; Return to caller
  312. BIN_2_ASC        endp
  313. ;
  314. CLOSE_FILE       proc    near           ; Close file handle
  315.         cmp      FILE_HANDLE,0          ; If 0, no file open
  316.         je       CLOSEX                 ; Do nothing
  317.         mov      bx,FILE_HANDLE         ; Move file handle to BX
  318.         mov      ah,3eh                 ; Request close file
  319.         int      21h                    ; Call PC-DOS
  320. CLOSEX: ret                             ; Return to caller
  321. CLOSE_FILE       endp
  322. CSEG    ends
  323.         end      BEGIN
  324.